package com.zhaoqi.hr.service;

import com.zhaoqi.hr.dto.request.AdminUserCreateRequest;
import com.zhaoqi.hr.dto.response.UserOptionResponse;
import com.zhaoqi.hr.entity.User;
import com.zhaoqi.hr.entity.UserDocument;
import com.zhaoqi.hr.entity.WorkContract;
import com.zhaoqi.hr.repository.JobApplicationRepository;
import com.zhaoqi.hr.repository.JobPostingRepository;
import com.zhaoqi.hr.repository.UserDocumentRepository;
import com.zhaoqi.hr.repository.UserRepository;
import com.zhaoqi.hr.repository.WorkContractRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.Predicate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户服务
 */
@Service
public class UserService {

    private static final Logger log = LoggerFactory.getLogger(UserService.class);

    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private UserDocumentRepository documentRepository;
    
    @Autowired
    private JobPostingRepository jobPostingRepository;
    
    @Autowired
    private JobApplicationRepository jobApplicationRepository;
    
    @Autowired
    private WorkContractRepository contractRepository;
    
    @Autowired
    private PasswordEncoder passwordEncoder;
    
    @Autowired
    private OssService ossService;

    /**
     * 获取平台统计数据
     */
    public Map<String, Object> getPlatformStatistics() {
        Map<String, Object> stats = new HashMap<>();
        
        // 用户统计
        long totalUsers = userRepository.count();
        long adminCount = userRepository.countByRole(User.UserRole.ADMIN);
        long employerCount = userRepository.countByRole(User.UserRole.EMPLOYER);
        long workerCount = userRepository.countByRole(User.UserRole.WORKER);
        long activeUsers = userRepository.countByStatus(User.UserStatus.APPROVED);
        
        stats.put("totalUsers", totalUsers);
        stats.put("adminCount", adminCount);
        stats.put("employerCount", employerCount);
        stats.put("workerCount", workerCount);
        stats.put("activeUsers", activeUsers);
        
        // 文档统计
        long totalDocuments = documentRepository.count();
        long pendingDocuments = documentRepository.countByAuditStatus(UserDocument.AuditStatus.PENDING);
        long approvedDocuments = documentRepository.countByAuditStatus(UserDocument.AuditStatus.APPROVED);
        
        stats.put("totalDocuments", totalDocuments);
        stats.put("pendingDocuments", pendingDocuments);
        stats.put("approvedDocuments", approvedDocuments);
        
        // 岗位统计
        long totalJobs = jobPostingRepository.count();
        long activeJobs = jobPostingRepository.countByStatus("PUBLISHED");
        
        stats.put("totalJobs", totalJobs);
        stats.put("activeJobs", activeJobs);
        
        // 申请统计
        long totalApplications = jobApplicationRepository.count();
        long pendingApplications = jobApplicationRepository.countByStatus("PENDING");
        
        stats.put("totalApplications", totalApplications);
        stats.put("pendingApplications", pendingApplications);
        
        // 合同统计
        long totalContracts = contractRepository.count();
        long activeContracts = contractRepository.countByStatus(WorkContract.ContractStatus.ACTIVE);
        
        stats.put("totalContracts", totalContracts);
        stats.put("activeContracts", activeContracts);
        
        log.info("获取平台统计数据完成");
        return stats;
    }

    /**
     * 获取用户列表（分页）
     */
    public Page<User> getUsers(Pageable pageable, User.UserRole role, User.UserStatus status) {
        Specification<User> spec = (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            
            if (role != null) {
                predicates.add(criteriaBuilder.equal(root.get("role"), role));
            }
            
            if (status != null) {
                predicates.add(criteriaBuilder.equal(root.get("status"), status));
            }
            
            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        };
        
        return userRepository.findAll(spec, pageable);
    }

    /**
     * 更新用户状态
     */
    @Transactional
    public void updateUserStatus(Long userId, User.UserStatus status, String reason) {
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
        
        User.UserStatus oldStatus = user.getStatus();
        user.setStatus(status);
        user.setUpdatedAt(LocalDateTime.now());
        
        userRepository.save(user);
        
        log.info("管理员更新用户状态，用户ID: {}, 原状态: {}, 新状态: {}, 原因: {}", 
                userId, oldStatus, status, reason);
    }

    /**
     * 根据ID获取用户
     */
    public User getUserById(Long userId) {
        return userRepository.findById(userId)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
    }

    /**
     * 根据手机号获取用户
     */
    public User getUserByPhone(String phone) {
        return userRepository.findByPhone(phone)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
    }

    /**
     * 检查用户是否存在
     */
    public boolean existsByPhone(String phone) {
        return userRepository.existsByPhone(phone);
    }

    /**
     * 获取用户详细信息（包含统计数据）
     */
    public Map<String, Object> getUserDetails(Long userId) {
        User user = getUserById(userId);
        Map<String, Object> details = new HashMap<>();
        
        details.put("user", user);
        
        // 根据用户角色获取相关统计
        if (user.getRole() == User.UserRole.EMPLOYER) {
            long jobCount = jobPostingRepository.countByEmployer_User_Id(userId);
            long contractCount = contractRepository.countByEmployer_User_Id(userId);
            details.put("jobCount", jobCount);
            details.put("contractCount", contractCount);
        } else if (user.getRole() == User.UserRole.WORKER) {
            long applicationCount = jobApplicationRepository.countByWorkerId(userId);
            long contractCount = contractRepository.countByWorker_User_Id(userId);
            long documentCount = documentRepository.countByUserId(userId);
            details.put("applicationCount", applicationCount);
            details.put("contractCount", contractCount);
            details.put("documentCount", documentCount);
        }
        
        return details;
    }

    /**
     * 搜索用户
     */
    public Page<User> searchUsers(String keyword, Pageable pageable) {
        if (keyword == null || keyword.trim().isEmpty()) {
            return userRepository.findAll(pageable);
        }
        
        return userRepository.findByRealNameContainingOrPhoneContaining(keyword, keyword, pageable);
    }

    /**
     * 批量更新用户状态
     */
    @Transactional
    public void batchUpdateUserStatus(List<Long> userIds, User.UserStatus status, String reason) {
        for (Long userId : userIds) {
            updateUserStatus(userId, status, reason);
        }
        log.info("批量更新用户状态完成，用户数量: {}, 状态: {}", userIds.size(), status);
    }

    /**
     * 管理员创建用户
     */
    @Transactional
    public User createUserByAdmin(AdminUserCreateRequest request) {
        // 检查手机号是否已存在
        if (userRepository.existsByPhone(request.getPhone())) {
            throw new RuntimeException("手机号已存在");
        }

        User user = new User();
        user.setUsername(request.getPhone()); // 使用手机号作为用户名
        user.setPhone(request.getPhone());
        user.setPassword(passwordEncoder.encode(request.getPassword()));
        user.setRealName(request.getRealName());
        user.setRole(request.getRole());
        user.setAddress(request.getAddress());
        user.setStatus(User.UserStatus.APPROVED); // 管理员创建的用户直接通过审核
        user.setCreatedAt(LocalDateTime.now());
        user.setUpdatedAt(LocalDateTime.now());

        User savedUser = userRepository.save(user);
        log.info("管理员创建用户成功: {}, 角色: {}", savedUser.getRealName(), savedUser.getRole());
        return savedUser;
    }

    /**
     * 删除用户
     */
    @Transactional
    public void deleteUser(Long userId) {
        log.info("开始删除用户: {}", userId);
        
        // 检查用户是否存在
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
        
        // 业务规则检查
        if (user.getRole() == User.UserRole.ADMIN) {
            throw new RuntimeException("不能删除管理员用户");
        }
        
        // 检查是否有进行中的合同或申请
        checkUserBusinessConstraints(userId, user.getRole());
        
        // 删除关联数据
        deleteUserRelatedData(userId);
        
        // 最后删除用户
        userRepository.deleteById(userId);
        log.info("用户删除成功: {} - {}", userId, user.getRealName());
    }
    
    /**
     * 检查用户业务约束
     */
    private void checkUserBusinessConstraints(Long userId, User.UserRole role) {
        if (role == User.UserRole.EMPLOYER) {
            // 检查是否有进行中的岗位发布
            // 这里可以添加具体的业务检查逻辑
            log.info("检查用工方用户业务约束: {}", userId);
        } else if (role == User.UserRole.WORKER) {
            // 检查是否有进行中的工作合同
            // 这里可以添加具体的业务检查逻辑
            log.info("检查劳动者用户业务约束: {}", userId);
        }
    }
    
    /**
     * 删除用户相关数据
     */
    private void deleteUserRelatedData(Long userId) {
        log.info("开始删除用户关联数据: {}", userId);
        
        // 删除用户文档
        List<UserDocument> documents = documentRepository.findByUserId(userId);
        for (UserDocument document : documents) {
            // 删除OSS文件
            try {
                ossService.deleteFile(document.getFilePath());
            } catch (Exception e) {
                log.warn("删除OSS文件失败: {}, 错误: {}", document.getFilePath(), e.getMessage());
            }
        }
        documentRepository.deleteByUserId(userId);
        log.info("删除用户文档完成: {}", userId);
        
        // 注意：EmployerProfile 和 WorkerProfile 会通过 User 实体的 cascade = CascadeType.ALL 自动删除
        // 如果需要手动删除，可以添加相应的删除逻辑
        
        log.info("用户关联数据删除完成: {}", userId);
    }
    
    /**
     * 获取用户选项列表（用于下拉选择）
     */
    public List<UserOptionResponse> getUserOptions(String search, int limit) {
        log.info("获取用户选项列表，搜索条件: {}, 限制数量: {}", search, limit);
        
        List<User> users;
        if (search != null && !search.trim().isEmpty()) {
            // 根据用户名或真实姓名搜索
            users = userRepository.findByUsernameContainingOrRealNameContainingOrderByCreatedAtDesc(
                search.trim(), search.trim(), org.springframework.data.domain.PageRequest.of(0, limit));
        } else {
            // 获取最新的用户
            users = userRepository.findAllByOrderByCreatedAtDesc(
                org.springframework.data.domain.PageRequest.of(0, limit));
        }
        
        return users.stream()
                .map(user -> new UserOptionResponse(
                    user.getId(),
                    user.getUsername(),
                    user.getRealName(),
                    user.getPhone(),
                    user.getRole().getDescription()
                ))
                .collect(java.util.stream.Collectors.toList());
    }
}
